from django.core.exceptions import ImproperlyConfigured
from django.db.transaction import commit_on_success
from django.db.models import fields, get_app
from django.http import Http404, HttpResponse
from owslib import wms
from duetopia.rdf.database import memory_model, get_model, make_rdf_annotations, w3type
from duetopia.rdf import dc, dct, dclite4g, foaf, ows
import RDF

__all__ = ["wms_import"]

def wms_import(request, app_label, module_name):
    """
    POST a very simple RDF/XML document describing a WMS
    GetCapabilities request. Read it with OWSLib.
    Shove the results into a Redland model.  
    """
    
    #django_model = get_model(app_label, module_name)
    #if not hasattr(django_model._meta, "rdf"):
    #    raise Http404("no RDF implementation")
    model = memory_model(request.raw_post_data)
    w = None
    for s in model.find_statements(RDF.Statement(None,w3type,ows.WMS.uri)):  
        w = s.subject
    if w is None:
        raise Http404("no WMS server found in POST data")
    model = wms_to_rdf_model(w,model)
    #django_model = get_model('register','dataset')
    try:
        django_model = get_model('register','dataset')
        
        s = RDF.Statement(None, w3type, dclite4g.DataSet.uri)
        for r in model.find_statements(s): 
            django_model.objects.rdf_get_or_create(model,r.subject)
        make_rdf_annotations(django_model,model)

    except Exception, e:
        print e
        raise

    # import, annotate
    return HttpResponse("OK")

def wms_to_rdf_model(w,model):
    
    """Accepts an RDF.Node containing a WMS, and a Redland model
    >>> w = RDF.Node(RDF.Uri("http://labs.metacarta.com/wms/vmap0"))
    >>> model = memory_model(None)
    >>> model = wms_to_rdf_model(w,model)
    >>> model.to_string()
    True
    """
    s = None
    try:
        s = wms.WebMapService(str(w.uri))
    except Exception, e:
        print e
        raise e
    # drop properties according to owslib into our model
    model.add_statement(RDF.Statement(w,w3type,dclite4g.Series.uri)) 
    model.add_statement(RDF.Statement(w,dc.title.uri,RDF.Node(s.identification.title)))
    model.add_statement(RDF.Statement(w,dct.abstract.uri,RDF.Node(s.identification.abstract)))
    for k in s.identification.keywords:
        model.add_statement(RDF.Statement(w,dc.subject.uri,RDF.Node(k)))
    # we likely will get duplicate contacts - resolve that later,
    # not during ingestion.
    contact = RDF.Uri(str(w)+'#contact')
    model.add_statement(RDF.Statement(contact,w3type,foaf.Person))
    model.add_statement(RDF.Statement(w,dc.contact.uri,contact))
    page = None
    if s.provider.url:
        page = s.provider.url
        model.add_statement(RDF.Statement(contact,foaf.page,RDF.Node(page)))
    #if wms.provider.name:
    #    model.add_statement(RDF.Statement(contact,foaf.name,RDF.Node(wms.provider.name)))
    if s.provider.contact:
        details = s.provider.contact
        if details.name: model.add_statement(RDF.Statement(contact,foaf.name,RDF.Node(details.name)))
        if details.email: model.add_statement(RDF.Statement(contact,foaf.mbox,RDF.URI('mailto'+str(details.email))))
        
        if details.organization:
            org = None
            if page:
                org = RDF.Uri(str(page)+'#organisation')
            else:
                org = RDF.Uri(str(w.uri)+'#organisation')
            model.add_statement(RDF.Statement(org,foaf.name,RDF.Node(details.organization)))
            # person-org relation where missing workplaceHomepage...?
    # layer data - each layer modelled as a dataset
    for k in s.contents.keys():
        layer = s[k]
        l = RDF.Uri(str(w.uri)+'#'+str(k))
        model.add_statement(RDF.Statement(l,w3type,dclite4g.DataSet.uri))
        model.add_statement(RDF.Statement(l,dclite4g.series,w))
        model.add_statement(RDF.Statement(l,dc.title.uri,RDF.Node(layer.title)))
        for k in layer.keywords:
            model.add_statement(RDF.Statement(w,dc.subject.uri,RDF.Node(k)))
        # missing extents data here.             
        # geometry and projection data 
    #print model.to_string()

    return model

#formats = self.wms.capabilities.getOperationByName('GetMap').formatOptions
#mimetype in ('image/png', 'image/jpeg', 'image/gif')
#            cw = {
#                'name': self.wms.capabilities.provider.name,
#                'email': self.wms.capabilities.provider.email,
#                'organization': org,
#                'position': self.wms.capabilities.provider.position,
#                'location': location,


if __name__ == '__main__':
        import doctest
        doctest.testmod()

